﻿using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
using DailyPoetryX.Models;
using DailyPoetryX.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Xamarin.Forms.Extended;

namespace DailyPoetryX.ViewModels {
    public class ResultPageViewModel : ViewModelBase {
        /******** 构造函数 ********/

        IContentNavigationService contentNavigationService;

        public ResultPageViewModel(IPoetryStorage poetryStorage,
            IContentNavigationService contentNavigationService) {
            this.contentNavigationService = contentNavigationService;

            Poetries = new InfiniteScrollCollection<Poetry> {
                OnCanLoadMore = () => canLoadMore,
                OnLoadMore = async () => {
                    Status = Loading;
                    var page = Poetries.Count / PageSize;
                    var poetries =
                        await poetryStorage.GetPeotriesAsync(Where,
                            page * PageSize, PageSize);

                    if (poetries.Count < PageSize) {
                        canLoadMore = false;
                        Status = NoMoreResult;
                    }

                    if (Poetries.Count == 0 && poetries.Count == 0) {
                        Status = NoResult;
                    }

                    return poetries;
                }
            };
        }

        /******** 绑定属性 ********/

        public string Status {
            get => _status;
            set => Set(nameof(Status), ref _status, value);
        }

        private string _status;

        public InfiniteScrollCollection<Poetry> Poetries { get; }

        public Expression<Func<Poetry, bool>> Where {
            get => _where;
            set {
                Set(nameof(Where), ref _where, value);
                newQuery = true;
            }
        }

        private Expression<Func<Poetry, bool>> _where;

        /******** 绑定命令 ********/

        public RelayCommand PageAppearingCommand =>
            _pageAppearingCommand ?? (_pageAppearingCommand = new RelayCommand(
                async () => {
                    var run = false;

                    if (newQuery) {
                        lock (newQueryLock) {
                            if (newQuery) {
                                newQuery = false;
                                run = true;
                            }
                        }
                    }

                    if (!run) return;

                    Poetries.Clear();
                    canLoadMore = true;
                    await Poetries.LoadMoreAsync();
                }));

        private RelayCommand _pageAppearingCommand;

        public RelayCommand<Poetry> PoetryTappedCommand =>
            _poetryTappedCommand ?? (_poetryTappedCommand =
                new RelayCommand<Poetry>(async poetry =>
                    await contentNavigationService.NavigateToAsync(
                        ContentNavigationServiceConstants.DetailPage, poetry)));

        private RelayCommand<Poetry> _poetryTappedCommand;

        /******** 私有变量 ********/

        private bool newQuery;
        private readonly object newQueryLock = new object();
        private bool canLoadMore;
        private const int PageSize = 20;
        private const string Loading = "正在载入";
        private const string NoResult = "没有满足条件的结果";
        private const string NoMoreResult = "没有更多结果";
    }
}